package com.bookstore.back.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.bookstore.back.entity.Book;
import com.bookstore.back.entity.BookTag;
import com.bookstore.back.mapper.BookMapper;
import com.bookstore.back.service.BookService;
import com.bookstore.back.service.BookTagRelationService;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.time.LocalDateTime;
import java.util.List;
import java.util.Map;

/**
 * 图书服务实现类
 * 
 * @author 程序猿_Ti
 * @since 2025-07-19
 */
@Service
public class BookServiceImpl extends ServiceImpl<BookMapper, Book> implements BookService {

    @Autowired
    private BookTagRelationService bookTagRelationService;

    @Override
    public IPage<Book> getBookList(Map<String, Object> params) {
        // 分页参数
        int current = Integer.parseInt(params.getOrDefault("current", "1").toString());
        int size = Integer.parseInt(params.getOrDefault("size", "10").toString());

        // 查询条件
        QueryWrapper<Book> queryWrapper = new QueryWrapper<>();

        // 标题搜索
        String title = (String) params.get("title");
        if (StringUtils.isNotBlank(title)) {
            queryWrapper.like("title", title);
        }

        // 作者搜索
        String author = (String) params.get("author");
        if (StringUtils.isNotBlank(author)) {
            queryWrapper.like("author", author);
        }

        // 分类筛选
        String categoryIdStr = (String) params.get("categoryId");
        if (StringUtils.isNotBlank(categoryIdStr)) {
            Integer categoryId = Integer.parseInt(categoryIdStr);
            if (categoryId > 0) {
                queryWrapper.eq("category_id", categoryId);
            }
        }

        // 状态筛选
        String statusStr = (String) params.get("status");
        if (StringUtils.isNotBlank(statusStr)) {
            Integer status = Integer.parseInt(statusStr);
            queryWrapper.eq("status", status);
        }

        // 按创建时间倒序
        queryWrapper.orderByDesc("created_at");

        IPage<Book> bookPage = this.page(new Page<>(current, size), queryWrapper);

        // 批量查询标签信息
        List<Book> books = bookPage.getRecords();
        if (!books.isEmpty()) {
            List<Integer> bookIds = books.stream().map(Book::getId).collect(java.util.stream.Collectors.toList());
            Map<Integer, List<BookTag>> bookTagsMap = bookTagRelationService.getTagsByBookIds(bookIds);

            // 为每本书设置标签信息
            for (Book book : books) {
                List<BookTag> tags = bookTagsMap.get(book.getId());
                book.setTags(tags != null ? tags : new java.util.ArrayList<>());
            }
        }

        return bookPage;
    }

    @Override
    @Transactional
    public boolean createBook(Book book) {
        // 验证标签数量
        if (book.getTagIds() != null && book.getTagIds().size() > 3) {
            throw new RuntimeException("图书标签最多只能选择3个");
        }

        // 设置默认值
        if (book.getStatus() == null) {
            book.setStatus(1); // 默认上架
        }
        if (book.getReviewCount() == null) {
            book.setReviewCount(0);
        }
        if (book.getSales() == null) {
            book.setSales(0);
        }
        if (book.getStock() == null) {
            book.setStock(0);
        }

        boolean result = this.save(book);

        // 保存标签关联
        if (result && book.getTagIds() != null && !book.getTagIds().isEmpty()) {
            bookTagRelationService.updateBookTags(book.getId(), book.getTagIds());
        }

        return result;
    }

    @Override
    @Transactional
    public boolean updateBook(Integer bookId, Book book) {
        // 验证标签数量
        if (book.getTagIds() != null && book.getTagIds().size() > 3) {
            throw new RuntimeException("图书标签最多只能选择3个");
        }

        book.setId(bookId);
        boolean result = this.updateById(book);

        // 更新标签关联
        if (result && book.getTagIds() != null) {
            bookTagRelationService.updateBookTags(bookId, book.getTagIds());
        }

        return result;
    }

    @Override
    public boolean deleteBook(Integer bookId) {
        return this.removeById(bookId);
    }

    @Override
    public boolean toggleBookStatus(Integer bookId, Integer status) {
        Book book = new Book();
        book.setId(bookId);
        book.setStatus(status);
        return this.updateById(book);
    }

    @Override
    public boolean batchDeleteBooks(List<Integer> bookIds) {
        return this.removeByIds(bookIds);
    }

    @Override
    public List<Book> getPopularBooks(Integer limit) {
        QueryWrapper<Book> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("status", 1) // 只查询上架的图书
                   .orderByDesc("sales") // 按销量倒序
                   .last("LIMIT " + (limit != null ? limit : 10));

        return this.list(queryWrapper);
    }

    @Override
    public Book getBookWithTags(Integer bookId) {
        Book book = this.getById(bookId);
        if (book != null) {
            List<BookTag> tags = bookTagRelationService.getTagsByBookId(bookId);
            book.setTags(tags);
        }
        return book;
    }

    @Override
    @Transactional
    public boolean updateBookTags(Integer bookId, List<Integer> tagIds) {
        // 验证标签数量
        if (tagIds != null && tagIds.size() > 3) {
            throw new RuntimeException("图书标签最多只能选择3个");
        }
        return bookTagRelationService.updateBookTags(bookId, tagIds);
    }

    @Override
    public List<Book> getRecommendedBooks(Integer limit) {
        QueryWrapper<Book> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("status", 1) // 只查询上架的图书
                   .orderByDesc("rating")    // 按评分倒序
                   .orderByDesc("sales")     // 按销量倒序
                   .orderByDesc("created_at") // 按创建时间倒序
                   .last("LIMIT " + (limit != null ? limit : 10));

        List<Book> books = this.list(queryWrapper);

        // 为每本书加载标签信息
        for (Book book : books) {
            List<BookTag> tags = bookTagRelationService.getTagsByBookId(book.getId());
            book.setTags(tags);
        }

        return books;
    }

    @Override
    public List<Book> getNewBooks(Integer limit) {
        QueryWrapper<Book> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("status", 1) // 只查询上架的图书
                   .ge("created_at", LocalDateTime.now().minusDays(365)) // 1年内创建的（扩大范围）
                   .orderByDesc("created_at") // 按创建时间倒序
                   .last("LIMIT " + (limit != null ? limit : 10));

        List<Book> books = this.list(queryWrapper);

        // 如果没有找到新书，则返回最新的图书
        if (books.isEmpty()) {
            queryWrapper = new QueryWrapper<>();
            queryWrapper.eq("status", 1)
                       .orderByDesc("created_at")
                       .last("LIMIT " + (limit != null ? limit : 10));
            books = this.list(queryWrapper);
        }

        // 为每本书加载标签信息
        for (Book book : books) {
            List<BookTag> tags = bookTagRelationService.getTagsByBookId(book.getId());
            book.setTags(tags);
        }

        return books;
    }

    @Override
    public List<Book> getPersonalizedBooks(Long userId, Integer limit) {
        QueryWrapper<Book> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("status", 1); // 只查询上架的图书

        if (userId != null) {
            // TODO: 基于用户行为的个性化推荐算法
            // 目前先返回评分和销量较高的图书
            queryWrapper.orderByDesc("rating")
                       .orderByDesc("sales");
        } else {
            // 未登录用户，返回热门图书
            queryWrapper.orderByDesc("sales")
                       .orderByDesc("rating");
        }

        queryWrapper.last("LIMIT " + (limit != null ? limit : 10));

        List<Book> books = this.list(queryWrapper);

        // 为每本书加载标签信息
        for (Book book : books) {
            List<BookTag> tags = bookTagRelationService.getTagsByBookId(book.getId());
            book.setTags(tags);
        }

        return books;
    }

}
